package biz

import (
	"errors"
	"fmt"
	"gorm.io/gorm"
	"sync"
)

type RedisDataOpService interface {
	Refresh(ids []int) error
	Clear(ids []int) error
}

type redisDataService struct {
	// 互斥锁是保证任意时刻只能有一个任务执行.以为此工具对于任务的并行执行没有意义
	mutex       sync.Mutex
	db          *gorm.DB
	recordRepo  RedisRecordRepo
	settingRepo RedisSettingRepo
}

func (srv *redisDataService) Refresh(ids []int) error {

	srv.mutex.Lock()
	defer srv.mutex.Unlock()

	var errchan = make(chan error, len(ids))

	var wg sync.WaitGroup
	wg.Add(len(ids))

	for _, id := range ids {

		go func(id int, ch chan error) {

			defer wg.Done()

			record := srv.recordRepo.Find(id)
			if record == nil {
				ch <- fmt.Errorf("未找到%v有效的记录", id)
				return
			}

			setting := srv.settingRepo.Find(record.TargetId)
			if setting == nil {
				ch <- fmt.Errorf("未找到%v有效的配置信息", id)
				return
			}

			data, err := parseData(srv.db, record)
			if err != nil {
				ch <- fmt.Errorf("数据解析失败:%w", err)
				return
			}

			mp := convertData(record.DataType, record.RedisKey, data)
			client := initRedisClient(setting)
			err = push(client, mp)
			if err != nil {
				ch <- fmt.Errorf("%v,刷新失败,错误信息: %w", id, err)
			}

		}(id, errchan)
	}

	wg.Wait()

	close(errchan)

	var err error
	for errval := range errchan {
		if err == nil {
			err = errval
		} else {
			err = fmt.Errorf("%v,%w", errval, err)
		}
	}
	return err
}

func (srv *redisDataService) Clear(ids []int) error {

	srv.mutex.Lock()
	defer srv.mutex.Unlock()
	var err error
	for _, id := range ids {
		record := srv.recordRepo.Find(id)
		if record == nil {
			return errors.New("未找到有效的记录")
		}

		setting := srv.settingRepo.Find(record.TargetId)
		if setting == nil {
			return errors.New("未找到有效的配置信息")
		}

		client := initRedisClient(setting)
		err = remove(client, record.RedisKey)

	}
	return err
}

func NewRedisOpService(db *gorm.DB, recordRepo RedisRecordRepo, settingRepo RedisSettingRepo) *redisDataService {
	return &redisDataService{sync.Mutex{}, db, recordRepo, settingRepo}
}
